package ext.cjt;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public final class ParameterFilter implements Filter {
	private static String split = "|";
	private static Boolean autoDetect;
	private static String paramNames = "";

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		if (!autoDetect) {
			if (!("".equalsIgnoreCase(paramNames))) {
				List<String> names = new ArrayList<String>();
				if (paramNames.contains(split)) {
					String[] ps = paramNames.split(split);
					for (int i = 0; i < ps.length; i++) {
						names.add(ps[i]);
					}
				} else {
					names.add(paramNames);
				}
				parseParams(names, request);
			}
		} else {
			autoParseParams(request);
		}
		chain.doFilter(request, response);
	}

	@SuppressWarnings("unchecked")
	private void parseParams(List<String> names, ServletRequest request) {
		//names:["params","anothername"]
		Enumeration<String> paramNames = request.getParameterNames();
		//map:{"params[0]":{"NM":"Andy","AGE":"20"},"params[1]":{"NM":"Bill","AGE":"22"}}
		Map<String, HashMap<String, String>> map = new HashMap<String, HashMap<String, String>>();
		for (Iterator<String> iter = names.iterator(); iter.hasNext();) {
			int length = 0;
			//prefixName:"params"
			String prefixName = (String) iter.next();
			while (paramNames.hasMoreElements()) {
				//fullName:"params[0].AGE"
				String fullName = paramNames.nextElement();
				//value:"20"
				String value = request.getParameter(fullName);
				//to match the string like "params[*].*"
				if (Pattern.matches(prefixName + "\\[(\\d+)\\]\\.(\\w)+", fullName)) {
					//mapKey:"params[0]"
					String mapKey = fullName.substring(0, fullName.indexOf("."));
					//subKey:"AGE"
					String subKey = fullName.substring(fullName.indexOf(".") + 1);
					if (map.containsKey(mapKey)) {
						Map<String, String> mapValue = map.get(mapKey);
						mapValue.put(subKey, value);
					} else {
						HashMap<String, String> tempMap = new HashMap<String, String>();
						tempMap.put(subKey, value);
						map.put(mapKey, tempMap);
						length++;
					}
				}
			}
			List<Map<String, String>> array = new ArrayList<Map<String, String>>();
			for (int i = 0; i < length; i++) {
				for (Iterator<Map.Entry<String, HashMap<String, String>>> iter2 = map.entrySet().iterator(); iter2.hasNext();) {
					Map.Entry<String, HashMap<String, String>> entry = iter2.next();
					//key:"params[0]"
					String key = entry.getKey();
					//value:{"NM":"Andy","AGE":"20"}
					HashMap<String, String> value = entry.getValue();
					int index = Integer.parseInt(key.substring(key.indexOf("[") + 1, key.indexOf("]")));
					if (i == index) array.add(value);
				}
			}
			request.setAttribute(prefixName, array);
		}
	}

	private void autoParseParams(ServletRequest request) {

	}

	public void init(FilterConfig config) throws ServletException {
		autoDetect = Boolean.parseBoolean(config.getInitParameter("autoDetect"));
		paramNames = config.getInitParameter("paramNames");
	}

	public void destroy() {
	}

}
